package pl.engine.renderer
{
	import flash.geom.Point;
	import pl.engine.camera.Camera;
	import pl.engine.model.IModel;
	import pl.engine.model.Model;
	import pl.engine.model.vo.BaseMapTile;
	import pl.engine.model.vo.obstacle.IBaseObstacle;
	import pl.engine.renderer.logic.ILogicRenderer;
	import pl.engine.view.IView;
	import pl.engine.view.View;
	import pl.world.actors.IAnimatedActor;
	import starling.core.Starling;



	/**
	 * ...
	 * @author Bakudo
	 */
	public class MapRenderer implements IMapRenderer
	{
		private var model:IModel;
		private var view:IView;
		private var logicRenderer:ILogicRenderer;

		public function MapRenderer( model:IModel, view:View, logicRenderer:ILogicRenderer )
		{
			this.logicRenderer = logicRenderer;
			this.model = model;
			this.view = view;
		}

		public function render():void
		{
			//trace('----------------\n\t\trender\n----------------');
			var gridSize:Point = Model.getGridSize();
			var tilePos:Point = Camera.tilePosition;
			var halfScreenW:uint = Math.floor( Camera.SCREEN_W * .5 );
			var halfScreenH:uint = Math.floor( Camera.SCREEN_H * .5 );
			var ox:uint;
			var oy:uint;

			// ox
			if (tilePos.x >= (gridSize.x - halfScreenW))
				ox = gridSize.x - 1;
			else if (tilePos.x < halfScreenW)
				ox = Camera.SCREEN_W - 1;
			else
				ox = tilePos.x + halfScreenW;

			// oy
			if (tilePos.y < halfScreenH )
				oy = 0;
			else if (tilePos.y >= (gridSize.y - halfScreenH))
				oy = gridSize.y - Camera.SCREEN_H;
			else
				oy = tilePos.y - halfScreenH;

			// dimX/dimY
			var dimX:uint = (ox - Camera.SCREEN_W) < 0 ? ox + 1 : Camera.SCREEN_W;
			var dimY:uint = (oy + Camera.SCREEN_H) < gridSize.y ? Camera.SCREEN_H : gridSize.y - oy;

			var i:uint = 0;
			var j:uint = 0;
			var n:uint = dimX * dimY;
			var m:uint;
			var sY:Number = oy;
			var tile:BaseMapTile;
			var obstacle:IBaseObstacle;

			while (i < n)
			{
				tile = model.getTileById( ox, oy );
				if (tile != null)
				{
					if (tile.isRendered == false)
					{
						// set bg
						view.setToBgLayer( tile );
						// set obstacles
						j = 0;
						m = tile.obstacles.length;
						while (j < m)
						{
							
							obstacle = tile.obstacles[j];
							if(obstacle.isRendered == false)
							{
								//TODO: zagadka na pozniej, czemu obstacle sa renderowane jak dopiero dodaje je do sceny
								view.setToObstacleLayer( obstacle );
								//throw new Error("MAM CIE!!!")
							}
							
							j++;
						}
						//trace('dodaje');
					}
				}

				if (oy % (dimY + sY - 1) == 0 && oy != 0)
				{
					oy = sY;
					ox--;
				}
				else
				{
					oy++;
				}
				i++;
			}

			// osobne renderowanie aktorow	
			// ...
			
			j = 0;
			m = logicRenderer.getActors().length;
			while (j < m)
			{
				obstacle = logicRenderer.getActors()[j];
				if (Camera.isInViewRange( obstacle.oX, obstacle.oY ) == true && obstacle.isRendered == false)
				{
					view.setToObstacleLayer( obstacle );
				}
				j++;
			}

			view.cleanUpBgLayer();
			view.cleanUpObstaclesLayer();
			view.setViewPosition( Starling.current.stage.stageWidth / 2 - Camera.iso.x, Starling.current.stage.stageHeight / 2 - Camera.iso.y );
			view.setCenterCrossPosition( Starling.current.stage.stageWidth / 2, Starling.current.stage.stageHeight / 2 );
		}
	}
}